/*
Copyright 2010 Iain Surgey.

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  

See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

*/
model_t *bspmodel;

int		CSE_bmins[2], CSE_bmaxs[2];
float	CSE_mins[2], CSE_maxs[2];

byte	vis_decompressed[MAX_MAP_LEAFS/8];

#define MAX_MODELS	10

model_t models[MAX_MODELS];
int nummodels;

#__body__

private var _bytes : ByteArray;


private function LoadBSP(mstr : String) {
	
	#{d|dheader_t *header}
	header = #{m| sizeof(dheader_t)};
	
	bspmodel = #{&models[nummodels]};
	nummodels++;
	
	_bytes = haxe.Resource.getBytes(mstr).getData();
	_bytes.endian = Endian.LITTLE_ENDIAN;
	
	#{header->ident = #[_bytes.readUnsignedInt()]#};
	#{header->version = #[_bytes.readUnsignedInt()]#};
	
	for ( i in 0...HEADER_LUMPS ) {
		#{header->lumps[#[i]#].fileofs = #[_bytes.readUnsignedInt()]#};
		#{header->lumps[#[i]#].filelen = #[_bytes.readUnsignedInt()]#};
	}
	
	Mod_LoadVertexes(#{&header->lumps[LUMP_VERTEXES]});
	Mod_LoadEdges (#{&header->lumps[LUMP_EDGES]});
	Mod_LoadSurfedges (#{&header->lumps[LUMP_SURFEDGES]});
	Mod_LoadLighting (#{&header->lumps[LUMP_LIGHTING]});
	Mod_LoadPlanes (#{&header->lumps[LUMP_PLANES]});
	Mod_LoadTexinfo (#{&header->lumps[LUMP_TEXINFO]});
	Mod_LoadFaces (#{&header->lumps[LUMP_FACES]});
	Mod_LoadMarksurfaces(#{&header->lumps[LUMP_LEAFFACES]});
	Mod_LoadLeafs (#{&header->lumps[LUMP_LEAFS]});
	Mod_LoadNodes (#{&header->lumps[LUMP_NODES]});
	Mod_LoadVisibility(#{&header->lumps[LUMP_VISIBILITY]});
	
	_bytes.length = 0;
	_bytes = null;
	
	flash.system.System.gc();
}




/*
=================
Mod_LoadVertexes
=================
*/
private function Mod_LoadVertexes (l : Int)
{
	#{s| lump_t *l}
	#{d| mvertex_t	*out}
	#{d| int			i, count}
	#{d| float v}
	
	_bytes.position = #{ l->fileofs };
	
	if ((#{l->filelen % sizeof(vec3)}) != 0)
		Sys_Error (ERR_DROP,"MOD_LoadVertexes: funny lump size for BSP model");
	count = Std.int(#{l->filelen / sizeof(vec3)});
	out = #{m| (count+8)*sizeof(vec3)};   	// extra for skybox

	#{bspmodel->vertexes = out};
	#{bspmodel->numvertexes = count};

	for ( i in 0...count)
	{
		
		for ( j in 0...3 ) {
			v = _bytes.readFloat();
			#{out->position.p[j] = v};
		}
		
		out += #{sizeof(vec3)};
	}
	
	for (i in 0...3) {
		#{bspmodel->mins[i] = 0};
		#{bspmodel->maxs[i] = 512};
	}
	
}


/*
=================
Mod_LoadEdges
=================
*/
private function Mod_LoadEdges (l : Int)
{
	#{s| lump_t *l}
	
	#{d| medge_t *out}
	#{d| int 	i, count}

	_bytes.position = #{ l->fileofs };
	if ((#{l->filelen % 4}) != 0)
		Sys_Error (ERR_DROP,"MOD_LoadEdges: funny lump size in BSP model");
	count = Std.int(#{l->filelen / 4});
	out = #{m| (count + 13) * sizeof(medge_t)};	// extra for skybox
	
	#{bspmodel->edges = out};
	#{bspmodel->numedges = count};

	for ( i in 0...count )
	{
		#{out->v[0] = #[_bytes.readUnsignedShort()]#};
		#{out->v[1] = #[_bytes.readUnsignedShort()]#};
		out += #{sizeof(medge_t)};
	}
}


/*
=================
Mod_LoadSurfedges
=================
*/
private function Mod_LoadSurfedges (l : Int)
{	
	#{s| lump_t *l}
	
	#{d| int 	i, count}
	#{d| int *out}
	
	_bytes.position = #{ l->fileofs };
	if ((#{l->filelen % sizeof(int)}) != 0)
		Sys_Error (ERR_DROP,"MOD_Loadsurfedges: funny lump size in BSP model");
	count = Std.int(#{l->filelen / sizeof(int)});
	out = #{m| (count+24)*sizeof(int)};	// extra for skybox

	#{bspmodel->surfedges = out};
	#{bspmodel->numsurfedges = count};
	
	for ( i in 0...count )
		#{out[i] = #[_bytes.readInt()]#};
	
}

/*
=================
Mod_LoadLighting

Converts the 24 bit lighting down to 8 bit
by taking the brightest component
=================
*/
private function Mod_LoadLighting (l : Int)
{
	#{s| lump_t *l}
	#{d| int 	i, size,v0,v1,v2}
	#{d| byte *out}
	
	if (#{l->filelen} <= 0)
	{
		#{bspmodel->lightdata = -1};
		return;
	}
	
	if ((#{l->filelen % 3}) != 0)
		Sys_Error (ERR_DROP,"MOD_LoadLighting: funny lump size in BSP model");
	
	size = Std.int(#{l->filelen/3});
	out = #{m| size};
	#{bspmodel->lightdata = out};
	_bytes.position = #{l->fileofs};
	for (i in 0...size)
	{
		v0 = _bytes.readUnsignedByte();
		v1 = _bytes.readUnsignedByte();
		v2 = _bytes.readUnsignedByte();
		if (v0 > v1 && v0 > v2)
			#{bspmodel->lightdata[i] = #[v0]#};
		else if (v1 > v0 && v1 > v2)
			#{bspmodel->lightdata[i] = #[v2]#};
		else
			#{bspmodel->lightdata[i] = #[v2]#};
	}
	
}

/*
=================
Mod_LoadPlanes
=================
*/
private function Mod_LoadPlanes (l : Int)
{
	#{s| lump_t *l}
	#{d| int			i, j,count,bits}
	#{d| mplane_t	*out}
	
	_bytes.position = #{l->fileofs};
	
	if ((#{l->filelen % sizeof(dplane_t)}) != 0)
		Sys_Error (ERR_DROP,"MOD_LoadPlanes: funny lump size in BSP model");
	count = Std.int(#{l->filelen / sizeof(dplane_t)});
	out = #{m| (count+6)*sizeof(mplane_t)};		// extra for skybox
	
	#{bspmodel->planes = out};
	#{bspmodel->numplanes = count};

	for ( i in 0...count )
	{
		bits = 0;
		for (j in 0...3)
		{
			#{out->normal.p[j] = #[_bytes.readFloat()]#};
			
			if (#{out->normal.p[j]} < 0)
				bits |= 1<<j;
		}

		#{out->dist = #[_bytes.readFloat()]#};
		#{out->type = #[_bytes.readInt()]#};
		#{out->signbits = bits};
		
		out += #{sizeof(mplane_t)};
	}
}

/*
=================
Mod_LoadTexinfo
=================
*/
private function Mod_LoadTexinfo (l : Int)
{
	#{s| lump_t *l}
	#{d| mtexinfo_t *out, *step}
	#{d| int 	i, j, count, next}
	#{d| float	len1, len2}
	var name : String;
	
	load_images = new Vector<LoadImg>();

	_bytes.position = #{l->fileofs};
	if ((#{l->filelen % sizeof(texinfo_t)}) != 0)
		Sys_Error (ERR_DROP,"MOD_LoadTexinfo: funny lump size in BSP model");
	count = Std.int(#{l->filelen / sizeof(texinfo_t)});
	out = #{m| (count+6)*sizeof(mtexinfo_t)};	// extra for skybox
	
	#{bspmodel->texinfo = out};
	#{bspmodel->numtexinfo = count};
	
	for ( i in 0...count )
	{
		for (j in 0...8 )
			#{out->vecs[0][j] = #[_bytes.readFloat()]#};
		len1 = VectorLength (#{out->vecs[0]});
		len2 = VectorLength (#{out->vecs[1]});
		len1 = (len1 + len2)/2;
		if (len1 < 0.32)
			#{out->mipadjust = 4};
		else if (len1 < 0.49)
			#{out->mipadjust = 3};
		else if (len1 < 0.99)
			#{out->mipadjust = 2};
		else
			#{out->mipadjust = 1};

		#{out->flags = #[_bytes.readInt()]#};
		_bytes.position += 4;
		name = _bytes.readUTFBytes(32);
		
		next = _bytes.readInt();
		if (next > 0)
			#{out->next = bspmodel->texinfo + (next*sizeof(mtexinfo_t)});
		
		#{out->image = -1};
		if (#{out->flags} & SURF_SKY == 0) PushImage(name,out);
		
		//#{out->image = #[R_FindImage (name, IT_WALL)]#};
		
		out += #{sizeof(mtexinfo_t)};
	}
}


/*
=================
Mod_LoadFaces
=================
*/
private function Mod_LoadFaces (l : Int)
{
	#{s| lump_t *l}
	#{d| msurface_t 	*out}
	#{d| int			i, count, surfnum,planenum,side}

	_bytes.position = #{l->fileofs};
	if ((#{l->filelen % sizeof(dface_t)}) != 0)
		Sys_Error (ERR_DROP,"MOD_LoadFaces: funny lump size in BSP model");
	count = Std.int(#{l->filelen / sizeof(dface_t)});
	out = #{m| (count+6)*sizeof(msurface_t)};	// extra for skybox

	#{bspmodel->surfaces = out};
	#{bspmodel->numsurfaces = count};
	
	out -= #{sizeof(msurface_t)};

	for ( surfnum in 0...count)
	{
		out += #{sizeof(msurface_t)};
		
		planenum = _bytes.readUnsignedShort();
		side = _bytes.readShort();
		
		#{out->firstedge = #[_bytes.readInt()]#};
		#{out->numedges = #[_bytes.readShort()]#};		
		if (#{out->numedges} < 3)
			Sys_Error (ERR_DROP,"Surface with "+#{out->numedges}+" edges");
		#{out->flags = 0};
		
		if (side != 0)
			#{out->flags = out->flags | SURF_PLANEBACK};

		#{out->plane = &bspmodel->planes[planenum]};
		#{out->texinfo = &bspmodel->texinfo[#[_bytes.readShort()]#]};
		
		CalcSurfaceExtents (out);
				
	// lighting info is converted from 24 bit on disk to 8 bit
		for (i in 0...MAXLIGHTMAPS)
			#{out->styles[i] = #[_bytes.readByte()]#};
		i = _bytes.readInt();
		if (i == -1)
			#{out->samples = #[-1]#};
		else
			#{out->samples = bspmodel->lightdata + #[Std.int(i/3)]#};
		
	// set the drawing flags flag
		if ((#{out->texinfo->flags} & SURF_SKY) != 0)
		{
			#{out->flags = out->flags | SURF_DRAWSKY};
			continue;
		}
	}
}

/*
=================
Mod_LoadMarksurfaces
=================
*/
private function Mod_LoadMarksurfaces (l : Int)
{	
	#{s| lump_t *l}
	#{d| int		i, j, count}
	#{d| msurface_t **out}
	
	_bytes.position = #{l->fileofs};
	
	if ((#{l->filelen} % 2) != 0)
		Sys_Error (ERR_DROP,"MOD_LoadMarksurfaces: funny lump size in BSP model");
	count = Std.int(#{l->filelen / 2});
	out = #{m| count*4};

	#{bspmodel->marksurfaces = out};
	#{bspmodel->nummarksurfaces = count};

	for ( i in 0...count )
	{
		j = _bytes.readUnsignedShort();
		if (j >= #{bspmodel->numsurfaces})
			Sys_Error (ERR_DROP,"Mod_LoadMarksurfaces: bad surface number");
		#{out[i] = bspmodel->surfaces + (j*sizeof(msurface_t))};
	}
}


/*
=================
Mod_LoadLeafs
=================
*/
private function Mod_LoadLeafs (l : Int)
{
	#{s| lump_t *l}
	
	#{d| mleaf_t 	*out}
	#{d| int			i, j, count,cluster}
	
	_bytes.position = #{l->fileofs};
	
	if ((#{l->filelen % sizeof(dleaf_t)}) != 0)
		Sys_Error (ERR_DROP,"MOD_LoadLeafs: funny lump size in BSP model");
	count = Std.int(#{l->filelen / sizeof(dleaf_t)});
	out = #{m| count*sizeof(mleaf_t)};
	
	#{bspmodel->leafs = out};
	#{bspmodel->numleafs = count};

	for ( i in 0...count )
	{
		#{out->contents = #[_bytes.readInt()]#};
		#{out->cluster = #[_bytes.readShort()]#};
		#{out->area = #[_bytes.readShort()]#};
		
		for (j in 0...6)
		{
			#{out->minmaxs[j] = #[_bytes.readShort()]#};
		}
		
		#{out->firstmarksurface = bspmodel->marksurfaces #[+ (_bytes.readUnsignedShort()*4)]# };
		#{out->nummarksurfaces = #[_bytes.readUnsignedShort()]#};
		
		_bytes.position += 4;
		
		out += #{sizeof(mleaf_t)};
	}
}


/*
=================
Mod_LoadNodes
=================
*/
private function Mod_LoadNodes (l : Int)
{
	#{s| lump_t *l}
	#{d| int			i, j, count, p}
	#{d| mnode_t 	*out}
	
	_bytes.position = #{l->fileofs};
	
	if ((#{l->filelen % sizeof(dnode_t)}) != 0)
		Sys_Error (ERR_DROP,"MOD_LoadNodes: funny lump size in BSP model");
	count = Std.int(#{l->filelen / sizeof(dnode_t)});
	out = #{m| count*sizeof(mnode_t)};
	
	#{bspmodel->nodes = out};
	#{bspmodel->numnodes = count};
	
	for ( i in 0...count )
	{
		#{out->plane = &bspmodel->planes[#[_bytes.readInt()]#]};
		
		for (j in 0...2)
		{
			p = _bytes.readInt();
			if (p >= 0)
				#{out->children[j] = &bspmodel->nodes[p]};
			else
				#{out->children[j] = &bspmodel->leafs[-1-p]};
		}
		
		
		for (j in 0...6)
		{
			#{out->minmaxs[j] = #[_bytes.readShort()]#};
		}
		
		#{out->firstsurface = #[_bytes.readUnsignedShort()]#};
		#{out->numsurfaces = #[_bytes.readUnsignedShort()]#};
		#{out->contents = CONTENTS_NODE};	// differentiate from leafs
		
		out += #{sizeof(mnode_t)};
	}
	
	Mod_SetParent (#{bspmodel->nodes}, -1);	// sets nodes and leafs
}

/*
=================
Mod_SetParent
=================
*/
private function Mod_SetParent (node : Int, parent : Int)
{
	#{s| mnode_t *node, *parent}
	
	#{node->parent = parent};
	if (#{node->contents} != CONTENTS_NODE)
		return;
	Mod_SetParent (#{node->children[0]}, node);
	Mod_SetParent (#{node->children[1]}, node);
}


/*
================
CalcSurfaceExtents

Fills in s->texturemins[] and s->extents[]
================
*/
private function CalcSurfaceExtents (s : Int)
{
	#{s| msurface_t *s}
	#{d| float val}
	#{d| int		i,j, e}
	#{d| mvertex_t	*v}
	#{d| mtexinfo_t	*tex}
	
	#{CSE_mins[0] = 999999};
	#{CSE_mins[1] = 999999};
	#{CSE_maxs[0] = -99999};
	#{CSE_maxs[1] = -99999};

	#{tex = s->texinfo};
	
	for (i in 0...#{s->numedges})
	{
		#{e = bspmodel->surfedges[s->firstedge+i]};
		if (e >= 0)
			#{v = &bspmodel->vertexes[bspmodel->edges[e].v[0]]};
		else
			#{v = &bspmodel->vertexes[bspmodel->edges[#[-e]#].v[1]]};
		
		for (j in 0...2)
		{
			val = #{v->position.p[0] * tex->vecs[j][0] 
					+ v->position.p[1] * tex->vecs[j][1] 
					+ v->position.p[2] * tex->vecs[j][2] 
					+ tex->vecs[j][3]};
			if (val < #{CSE_mins[j]})
				#{CSE_mins[j] = val};
			if (val > #{CSE_maxs[j]})
				#{CSE_maxs[j] = val};
		}
	}

	for (i in 0...2)
	{	
		#{CSE_bmins[i] = #[Math.floor(]#CSE_mins[i]/16)};
		#{CSE_bmaxs[i] = #[Math.ceil(]#CSE_maxs[i]/16)};
		
		#{s->texturemins[i] = CSE_bmins[i] * 16};
		#{s->extents[i] = (CSE_bmaxs[i] - CSE_bmins[i]) * 16};
		if (#{s->extents[i]} < 16)
			#{s->extents[i] = 16};
	}
}

/*
=================
Mod_LoadVisibility
=================
*/
private function Mod_LoadVisibility (l : Int)
{
	#{s| lump_t *l}
	#{d| int		i}

	if (#{l->filelen} < 1)
	{
		#{bspmodel->vis = -1};
		return;
	}
	
	#{m| bspmodel->vis = l->filelen};
	__m__.position = #{bspmodel->vis};
	__m__.writeBytes(_bytes,#{l->fileofs},#{l->filelen});
	
	_bytes.position = #{l->fileofs};
	#{bspmodel->vis->numclusters = #[_bytes.readInt()]#};
	for (i in 0...#{bspmodel->vis->numclusters})
	{
		#{bspmodel->vis->bitofs[i] = #[_bytes.readInt()]#};
		_bytes.readInt();
	}
}


/*
===============
Mod_PointInLeaf
===============
*/
private function Mod_PointInLeaf () : Int
{
	//#{s| vec3 p}
	//#{s| model_t *model}
	#{d| mnode_t		*node}
	#{d| float		d}
	#{d| mplane_t	*plane}
	
	var i : Int = 0;
	
	if (#{currentmodel->nodes} < 4)
		Sys_Error (ERR_DROP, "Mod_PointInLeaf: bad model");

	node = #{currentmodel->nodes};
	while (true)
	{
		
		if (#{node->contents} != -1) {
			return node;
		}
		plane = #{node->plane};
		d = DotProduct (#{r_origin},#{&plane->normal}) - #{plane->dist};
		if (d > 0)
			node = #{node->children[0]};
		else
			node = #{node->children[1]};
	}
	
	return 0;	// never reached
}

/*
==============
Mod_ClusterPVS
==============
*/
private inline function Mod_ClusterPVS (cluster : Int)
{
	#{s| int cluster}
	var out : Int;
	if (cluster == -1 || #{currentmodel->vis} < 4) {
		out = 0;
	} else {
		Mod_DecompressVis ( #{currentmodel->vis} + #{currentmodel->vis->bitofs[cluster]});
		out = #{vis_decompressed};
	}
	return out;
}

/*
===================
Mod_DecompressVis
===================
*/
private inline function Mod_DecompressVis (vin : Int)
{
	#{d| int		c, out, row}
	
	row = (#{currentmodel->vis->numclusters}+7)>>3;	
	out = #{vis_decompressed};
	
	if (vin < 4)
	{	// no vis info, so make all visible
		while (row != 0)
		{
			Memory.setByte(out++,0xff);
			row--;
		}	
	}
	else
	{
		do
		{
			c = Memory.getByte(vin);
			if (c != 0)
			{
				Memory.setByte(out++,c);
				vin++;
				continue;
			}
		
			c = Memory.getByte(vin+1);
			vin += 2;
			while (c != 0)
			{
				Memory.setByte(out++,0);
				c--;
			}
		} while (out - #{vis_decompressed} < row);
	}
	
	return #{vis_decompressed};
}


/*
=================
Mod_LoadAliasModel
=================
*/
private function Mod_LoadAliasModel (fname : String)
{
	#{d| amodel_t *mod}
	#{d| 	int			ident,version}
	#{d| int			ofs_skins,ofs_st,ofs_tris}
	#{d| int			ofs_frames,ofs_end, ofs_edges, num_edges, framesize}
	#{d| float scale0, scale1, scale2, v0, v1, v2}
	#{d| float min0, min1, min2, max0, max1, max2}
	#{d| int d0, d1, d2}
	#{d| daliasframe_t *curframe}
	#{d| int i, j, k}
	
	mod = #{m| sizeof(amodel_t)};
	
	var modbytes : ByteArray;
	
	modbytes = haxe.Resource.getBytes(fname).getData();
	modbytes.endian = Endian.LITTLE_ENDIAN;
	modbytes.position = 0;
	
	ident = modbytes.readInt();
	version = modbytes.readInt();
	#{mod->skinwidth = #[modbytes.readInt()]#};
	#{mod->skinheight = #[modbytes.readInt()]#};
	#{mod->framesize = #[modbytes.readInt()]#};
	framesize = #{mod->framesize};
	modbytes.position += 4; //num_skins
	#{mod->num_xyz = #[modbytes.readInt()]#};
	#{mod->num_st = #[modbytes.readInt()]#};
	#{mod->num_tris = #[modbytes.readInt()]#};
	modbytes.position += 4; //num_glcmds
	#{mod->num_frames = #[modbytes.readInt()]#};
	ofs_skins = modbytes.readInt();
	ofs_st = modbytes.readInt();
	ofs_tris = modbytes.readInt();
	ofs_frames = modbytes.readInt();
	modbytes.position += 4; //ofs_glcmds
	ofs_edges = modbytes.readInt();
	num_edges = modbytes.readInt();
	ofs_end = modbytes.readInt();
	
	if (version != ALIAS_VERSION)
		Sys_Error (ERR_DROP, fname+" has wrong version number ("+version+" should be "+ALIAS_VERSION+")");
	
	if (#{mod->skinheight} > MAX_LBM_HEIGHT*2)
		Sys_Error (ERR_DROP, "model "+fname+" has a skin taller than "+MAX_LBM_HEIGHT);

	if (#{mod->num_xyz} <= 0)
		Sys_Error (ERR_DROP, "model "+fname+" has no vertices");

	if (#{mod->num_xyz} > MAX_VERTS)
		Sys_Error (ERR_DROP, "model "+fname+" has too many vertices");

	if (#{mod->num_st} <= 0)
		Sys_Error (ERR_DROP, "model "+fname+" has no st vertices");

	if (#{mod->num_tris} <= 0)
		Sys_Error (ERR_DROP, "model "+fname+" has no triangles");
	
	modbytes.position = ofs_st;
	ofs_st = #{m| mod->num_st*sizeof(stvert_t)};
	#{mod->st = ofs_st};
//
// load base s and t vertices (not used in gl version)
//
	
	for (i in 0...#{mod->num_st})
	{
		#{mod->st[i].s = #[modbytes.readShort()]#};
		#{mod->st[i].t = #[modbytes.readShort()]#};
	}
	
//
// load triangle lists
//
	modbytes.position = ofs_tris;
	ofs_tris = #{m| mod->num_tris*sizeof(triangle_t)};
	#{mod->tris = ofs_tris};
	
	for (i in 0...#{mod->num_tris})
	{
		for (j in 0...3)
		{
			#{mod->tris[i].index_xyz[j] = #[modbytes.readShort()]#};
		}
		for (j in 0...3) {
			#{mod->tris[i].index_st[j] = #[modbytes.readShort()]#};
		}
	}
	
//
// load the verts
//
	modbytes.position = ofs_frames;
	ofs_frames = #{m| mod->framesize*mod->num_frames};
	#{mod->frames = ofs_frames};
	curframe = ofs_frames;
	
	for (i in 0...#{mod->num_frames}) {
		for (j in 0...3) {
			#{curframe->scale[j] = #[modbytes.readFloat()*2.5]#};
		}
		
		for (j in 0...3) {
			#{curframe->translate[j] = #[modbytes.readFloat()]#};
		}
		
		modbytes.position += 16;
		
		for (j in 0...#{mod->num_xyz})
			for (k in 0...4)
				#{curframe->verts[j].v[k] = #[modbytes.readByte()]# };
		
		curframe += framesize;
	}
	
	#{mod->skin = #[R_FindImage(fname+"skin", IT_SKIN)]#};
	s_pmdl = mod;
	
	#{s_pmdl->origin[0] = 0};
	#{s_pmdl->origin[1] = 0};
	#{s_pmdl->origin[2] = 0};
	
	#{s_pmdl->frame = 0};
	#{s_pmdl->backlerp = 1};
	
	modbytes.length = 0;
}


